package top.xunfong.redis.factory;

import cn.hutool.core.util.ObjectUtil;
import top.xunfong.redis.listener.ExpirationListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 过期监听工厂
 */
@Component
public class ExpirationListenerFactory {
    private final ApplicationContext applicationContext;

    /**
     * 缓存所有ExpirationListener
     */
    private final Map<String, ExpirationListener> expirationListenerMap = new HashMap<>();

    /**
     * 匹配Key
     */
    private List<String> ExpirationListenerKeyList;

    @Autowired
    public ExpirationListenerFactory(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
        Collection<ExpirationListener> values = applicationContext.getBeansOfType((ExpirationListener.class)).values();
        for (ExpirationListener expirationListener : values) {
            if (ObjectUtil.isNull(expirationListener.getRedisKey())) {
                throw new IllegalStateException("ExpirationListener.getRedisKey()不能为空");
            }
            if (expirationListenerMap.containsKey(expirationListener.getRedisKey())) {
                throw new IllegalStateException("ExpirationListener.getRedisKey()不能重复");
            }
            expirationListenerMap.put(expirationListener.getRedisKey(), expirationListener);
        }
        // 遍历完之后，给key排序，长的优先匹配，短的后匹配
        this.ExpirationListenerKeyList = expirationListenerMap.keySet().stream().sorted((s1, s2) -> Integer.compare(s2.length(), s1.length())).toList();
    }

    /**
     * 传入redisKey，匹配到的ExpirationListener
     *
     * @param redisKey
     * @return
     */
    public ExpirationListener getExpirationListener(String redisKey) {
        for (String key : ExpirationListenerKeyList) {
            if (redisKey.startsWith(key)) {
                return expirationListenerMap.get(key);
            }
        }
        return null;
    }


//    public ExpirationListener getExpirationListener(Class<? extends ExpirationListener> clazz) {
//        return applicationContext.getBean(clazz);
//    }

//    public ExpirationListener getExpirationListener(String beanName) {
//        return applicationContext.getBean(beanName, ExpirationListener.class);
//    }

}
